﻿using HtmlAgilityPack;
using ScrapperBase;
using SoccerGameSpider.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SoccerGameSpider
{
    public class FranceMatchLoader: MatchLoader
    {
        private const string FranceUrl = @"http://www.foot-national.com/{0}";

        protected override string UrlFormat
        {
            get { return FranceUrl; }
        }

        protected override TeamStats GetTeamStats(HtmlDocument matchDoc, HomeAway homeAway)
        {
            string className = "table equipe1";
            Team team = this.match.HomeTeam;

            if (homeAway == HomeAway.Away)
            {
                className = "table equipe2";
                team = this.match.AwayTeam;
            }

            string path = string.Format("//table[@class='{0}']", className);
            HtmlNode table = matchDoc.DocumentNode.SelectSingleNode(path);

            var teamStats = new TeamStats();

            teamStats.Team = team;
            teamStats.HomeAway = homeAway;

            this.LoadPlayers(teamStats, table, this.match.MatchTime);

            return teamStats;
        }

        private void LoadPlayers(TeamStats teamStats, HtmlNode teamTable, DateTime matchTime)
        {
            HtmlNodeCollection rows = teamTable.SelectNodes("./tr");

            TopBench topBench = TopBench.Top;

            foreach (HtmlNode tr in rows)
            {
                if (tr.InnerText == "JOUEURS")
                {
                    topBench = TopBench.Top;
                    continue;
                }

                if (tr.InnerText == "REMPLAÇANTS")
                {
                    topBench = TopBench.Bench;
                    continue;
                }

                if (tr.InnerText == "ENTRAINEUR")
                {
                    //when the text is "coach", no more player
                    break;
                }

                PlayerStats playerStats = this.GetPlayerStats(teamStats, tr, topBench, matchTime);
                teamStats.Players.Add(playerStats);
            }

            teamStats.YellowCards = teamStats.Players.Sum(ps => ps.YellowCards);
            teamStats.RedCards = teamStats.Players.Sum(ps => ps.RedCards);
        }

        private PlayerStats GetPlayerStats(TeamStats teamStats, HtmlNode row, TopBench topBench, DateTime matchTime)
        {
            PlayerStats playerStat = new PlayerStats();

            HtmlNode infoNode = row.ChildNodes[2];

            var hrefNode = infoNode.Descendants().First(node => node.Attributes["href"] != null);
            var playerLink = hrefNode.GetAttributeValue("href", string.Empty);

            int index = playerLink.IndexOf('-');
            var playerKey = playerLink.Remove(index);
            string playerName = infoNode.FirstChild.InnerText;

            playerStat.Player = teamStats.Team.GetPlayer(playerKey, playerName, matchTime);
            playerStat.TopBench = topBench;
            playerStat.Position = GetPosition(row.ChildNodes[3].InnerText);

            HtmlNodeCollection imgNodes = infoNode.SelectNodes("./img");

            if (imgNodes == null)
            {
                return playerStat;
            }

            foreach (HtmlNode img in imgNodes)
            {
                var matchEvent = GetMatchEvent(img);

                if (matchEvent == null)
                {
                    continue;
                }

                switch (matchEvent.EventType)
                {
                    case EventType.Goal:
                        playerStat.Goals++;
                        break;
                    case EventType.OwnGoal:
                        playerStat.OwnerGoals++;
                        break;
                    case EventType.RedCard:
                        playerStat.RedCards++;
                        break;
                    case EventType.YellowCard:
                        playerStat.YellowCards++;
                        break;
                    case EventType.SwitchOut:
                        playerStat.IsSwitchOut = true;
                        break;
                    default:
                        break;
                }

                playerStat.MatchEvents.Add(matchEvent);
            }

            return playerStat;
        }

        private Position GetPosition(string posMark)
        {
            switch (posMark.ToUpper())
            {
                case "GAR":
                    return Position.GoalKeeper;
                case "DEF":
                    return Position.Defense;
                case "MIL":
                    return Position.Midfield;
                case "ATT":
                    return Position.Forward;
                default:
                    return Position.Unknown;
            }
        }

        private MatchEvent GetMatchEvent(HtmlNode imageNode)
        {
            string imgUrl = imageNode.Attributes["src"].Value;

            EventType eventType = ConvertFromImage(imgUrl);

            if (eventType == EventType.Unknown)
            {
                return null;
            }

            MatchEvent matchEvent = new MatchEvent();
            matchEvent.EventType = eventType;

            string minuteText = imageNode.NextSibling.InnerText;

            if (string.IsNullOrEmpty(minuteText.Trim()))
            {
                return matchEvent;
            }

            matchEvent.EventMinute = int.Parse(minuteText.TrimEnd(' ', '\''));

            return matchEvent;
        }

        private EventType ConvertFromImage(string imgUrl)
        {
            string imageName = imgUrl.Substring(imgUrl.LastIndexOf('/') + 1);

            switch (imageName)
            {
                case "ico_but.png":
                    return EventType.Goal; //Goal
                case "ico_butannule.png":
                    return EventType.OwnGoal; //Own Goal
                case "ico_jaune.png":
                    return EventType.YellowCard; //Yellow Card 
                case "ico_rouge.png":
                    return EventType.RedCard; //Red Card
                case "ico_sortie.png":
                    return EventType.SwitchOut; //Switch out
                case "ico_entree.png":
                    return EventType.SwitchIn; //Substitution
                default:
                    return EventType.Unknown;
            }
        }
    }
}
